iT邦幫忙

2023 iThome 鐵人賽

DAY 10
0
自我挑戰組

重新複習JavaScript系列 第 10

[Day -10] 運算子(Operator)(1)

  • 分享至 

  • xImage
  •  

應該不會有人覺得我今天要講scope chain,雖然我昨天斷在這個地方,但那真的有點難,我打算放在比較後面來複習XD

今天主要是來講 運算子(Operator) 以及他們的 優先權(precedence)相依性(associativity)

名詞解釋

運算子(Operator)

運算子(Operator),也就是我們在數學上常看到的運算符號。

var a = 3 + 4

這段簡單的code中 + 就是運算子。

但這時候有一個問題,為什麼JavaScript會知道這段code要相加?

我們必須要了解他的底層:

當JavaScript引擎看到+這個運算符號時,他會去呼叫下面這個函式(+其實是一個函式)

function add(a, b) {
  return
}

但我不用add命名,而是用+

function +(a, b) {
  return
}

因此,這段code其實會是長這樣:

var a = +(3, 4)

但由於這樣寫實在太麻煩了,因此就有了以下這些寫法:

Prefix Notation: + 3 4
Infix Notation 3 + 4
Postfix Notation 3 4 +

像我們因為從小就是用3 + 4這樣的方式來讀,因此採用 Infix Notation會方便我們閱讀
但記住本質上他還是一個有兩個參數的函式調用

優先權(precedence)

precedence(優先權):哪個運算子會被優先呼叫。

在同一行程式中,如果不只有一個運算子時,運算子會依優先權的高低被呼叫,而 JavaScript 會先處理高優先權的運算子,然後依序到低優先性權運算子。

相依性(associativity)

associativity(相依性):運算子被呼叫的順序,有分為左相依性 (從左到右) 和右相依性 (從右到左)。

當同一行程式中,我們有多個相同優先性的運算子時,我們就要看相依性是如何,來判斷是從左到右還是從右到左呼叫。

下面這張圖是來自[MDN]
我們可以清楚看到剛剛我們所介紹的運算子(Operator) 、 優先權(precedence) 跟 相依性(associativity)

了解這些名詞的意思後我們可以繼續往下走。

運算子的種類

MDN 上有列出十種的運算子分類,這邊就不一一列出,大家有興趣可以直接到MDN去查看。

這邊主要介紹最常見的五個運算子:

  • 算術運算子(arithmetic operators)
  • 賦值運算子(assignment operators)
  • 比較運算子 (comparison operators)
  • 邏輯運算子(Logical operators)
  • 條件(三元)運算子(Conditional (ternary) operator)

今天這篇會先以前三個,剩下兩個是明天的內容。

算術運算子

包含了最基本的數學四則運算的符號,讓你可以對兩組值(value)進行加、減、乘、除。

Imgur

算術運算子比較容易讓人弄不清楚的是遞加++和遞減--

你會在程式碼裡面看到兩種寫法(+跟-觀念相同所以只用+舉例):

let x = 3
console.log(x)       // 會印出 3 
console.log(x++)     // 會印出 3 ( 將 ++ 寫在變數後面 )
console.log(x)       // 會印出 4
console.log(++x)     // 會印出 5 ( 將 ++ 寫在變數前面 )

兩種都是代表「將 x 的值加上1」,但差別就在於:

console.log(x++) 的執行順序是:先列印出 x 的數值後,再進行 x = x + 1 的動作;

console.log(++x) 的執行順序是: x 的數值會先進行 x = x + 1 的運算,再列印結果。

賦值運算子

在變數那章節有提到 = 這個符號,要把它看作是賦值,因為它是一種賦值運算子。

Imgur

比較運算子

比較運算子陳述的是邏輯關係,他會對前後的 value 進行比較,然後回傳 boolean 值,也就是 true 或是 false

這部分最讓我們困惑的應該就是 ===== 以及 !=!== 吧,其他其實跟數學差不多。

== 我們可以說:他是一個寬鬆的等於,直接看例子:

 console.log(1 == '1')

剛學完資料型別的我們想必很清楚知道答案吧,答案就是false……什麼!!!為什麼是true !!!

因為使用**==** 不會特別判斷兩邊的資料型別是否不同,因此會發生許多難以掌握的狀況。

而使用 **===** 則會進一步比較資料型別是否相等,因此在撰寫 JavaScript 時一定要記得使用 **===**

在 重量級著作 JavaScript: The Good Parts 裡,Douglas Crockford 說得非常清楚:「我的建議是永遠不要使用這對邪惡的雙胞胎 (指 == 和 !=),永遠使用 === 和 !==。」


延伸題型

既然都瞭解了運算子(Operator) 、 優先權(precedence) 跟 相依性(associativity),以及3種運算子,這邊來一些進階的題目。

先暖身:

var a = 3 + 4 * 5;

小時候都學過先乘除後加減,因此答案很簡單是:23。
但在程式上是怎麼算出來的?
這邊要記住所有的運算符號其實都是function,因此這段code可以看成是一組2個function的調用,又加上JavaScript引擎是 synchronous處理code,所以他會分段調用優先權較高運算子,因此會先調用*(優先權13)再調用(優先權12)所以才會得到23。

了解基礎後我們來看看下個案例:

var a = 2, b = 3, c = 4;
a = b = c;
console.log(a) //4
console.log(b) //4
console.log(c) //4

為什麼全部都是4呢?

因為associativity,讓我們看到連結的表單。當今天我們在程式碼上看到 = 時,請把他看作是賦值運算子。因此我們找到賦值的欄位可以看到他的associativity是由右至左,因此我們在這行code要先處理的是b = c。
所以實際的code換成比較好閱讀會是:

var a = 2, b = 3, c = 4;
b = c; 
a = b;

由於這些是屬於number,因此我們直接傳值,所以才會輸出全部都是4。


就像前面說的,今天這篇會先介紹前面三個運算子,剩下兩個是明天的內容。

是因為加上去篇幅會太長,才忍痛分成兩篇的,絕對不是為了湊天數的XD

所以,明天見摟~


上一篇
[Day -9] 了解function底層運作邏輯
下一篇
[Day -11] 運算子(Operator)(2)
系列文
重新複習JavaScript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言